//生成dom队列
function dp(pageString) {
  let domElement = {}
  pageString = pageString.replaceAll('\n', '').replaceAll('\t', '')
  let content = document.createElement('div')
  content.innerHTML = pageString
  domList(content.childNodes[0], domElement)
  return {
    element: content.childNodes[0],
    children: domElement,
  }
}

//生成dom队列
function domList(dom, domElement) {
  initDomFunctions(dom)
  if (
    dom.getAttribute != null &&
    dom.getAttribute('ref') != '' &&
    dom.getAttribute('ref') != null
  ) {
    domElement[dom.getAttribute('ref')] = dom
  }
  if (dom.childNodes.length > 0) {
    dom.childNodes.forEach((node) => {
      domList(node, domElement)
    })
  }
}

function dc(tag, Class) {
  let element = document.createElement(tag)
  if (Class != null) {
    if (typeof Class == 'string') {
      element.classList.add(Class)
    } else {
      Class.forEach((className) => {
        element.classList.add(className)
      })
    }
  }
  element['txt'] = (text) => {
    element.innerText = text
    return element
  }
  element['add'] = (ele) => {
    element.appendChild(ele)
    return element
  }
  element['show'] = (display) => {
    if (display == null) {
      element.style.display = 'block'
    } else {
      element.style.display = display
    }
  }
  element['hide'] = () => {
    element.style.display = 'none'
  }
  element['val'] = (val) => {
    element.value = val
    return element
  }
  return element
}

//初始化Dom的函数
function initDomFunctions(dom) {
  dom['show'] = (display) => {
    if (display == null) {
      dom.style.display = 'block'
    } else {
      dom.style.display = display
    }
  }
  dom['hide'] = () => {
    dom.style.display = 'none'
  }
  dom['val'] = (val) => {
    dom.value = val
  }
  dom['txt'] = (text) => {
    dom.innerText = text
  }
}

// 传入变量判断其是否是数字
// 是：返回整数
// 否：返回false
function toNum(inputContent) {
  // 将输入内容转换成字符串
  inputContent = String(inputContent)

  // 检查输入内容是否为数字
  if (!isNaN(inputContent)) {
    // 如果是数字，返回数字或取整后的数字
    if (inputContent.includes('.')) {
      return Math.floor(parseFloat(inputContent)) // 返回取整后的数字
    } else {
      return parseInt(inputContent) // 返回整数
    }
  } else {
    // 如果不是数字，返回 false
    return false
  }
}

class HTMLShower extends HTMLElement {
  constructor() {
    super()
    this.codeString = ''
    this.pList = []
  }
  set dark(dark) {
    if (dark == 'true') {
      document.body.style.setProperty('--CODEBORDER', ' #dbdbdb')
      document.body.style.setProperty('--CODEBACKGROUNDCOLOR', '#363636')
      document.body.style.setProperty('--CODENOBORDERRIGHT', '#dbdbdb')
      document.body.style.setProperty('--PHOVERBACKGROUNDCOLOR', '#323232')
      document.body.style.setProperty('--NOCOLOR', '#cccccc')
      document.body.style.setProperty('--TAGCOLOR', '#569cd6')
      document.body.style.setProperty('--TAGNAMECOLOR', '#569cd6')
      document.body.style.setProperty('--TAGATTUBITECOLOR', '#9cdcfe')
      document.body.style.setProperty('--TAGEQUALCOLOR', '#fff')
      document.body.style.setProperty('--TAGATTUBITEINNERCOLOR', '#ce9178')
      document.body.style.setProperty('--TAGFONTCOLOR', '#fff')
    } else {
      document.body.style.setProperty('--CODEBORDER', ' #dbdbdb')
      document.body.style.setProperty('--CODEBACKGROUNDCOLOR', '#fff')
      document.body.style.setProperty('--CODENOBORDERRIGHT', '#dbdbdb')
      document.body.style.setProperty('--PHOVERBACKGROUNDCOLOR', '#fafafa')
      document.body.style.setProperty('--NOCOLOR', '#38444b')
      document.body.style.setProperty('--TAGCOLOR', '#2367c7')
      document.body.style.setProperty('--TAGNAMECOLOR', '#2367c7')
      document.body.style.setProperty('--TAGATTUBITECOLOR', '#cb2d01')
      document.body.style.setProperty('--TAGEQUALCOLOR', '#38444b')
      document.body.style.setProperty('--TAGATTUBITEINNERCOLOR', '#248c85')
      document.body.style.setProperty('--TAGFONTCOLOR', '#38444b')
    }
    this.setAttribute('dark', dark)
  }
  get dark() {
    return this.getAttribute('dark')
  }

  connectedCallback() {
    this.dark = this.getAttribute('dark')
    this.element = dp(`<div class="a-code">
        <div class="a-code-top-tool-bar">
            <div class="a-code-title" ref="title"></div>
            <div class="a-code-tip" ref="tip"></div>
            <i class="icon-file-copy-line" ref="copy"></i>
        </div>
        <div class="a-code-bottom-code">
            <div ref="codeNo" class="a-code-no"></div>
            <div ref="codeContent" class="a-code-content scroll"></div>
        </div>
    </div>`)
    this.refs = this.element.children
    if (this.getAttribute('title') != null) {
      this.refs.title.innerText = this.getAttribute('title')
      this.setAttribute('title', '')
    }
    this.refs.copy.onclick = () => {
      this.copy()
    }
    this.codeString = this.innerHTML + ''
    let innerText = this.innerHTML + ''
    this.innerHTML = ''
    innerText = innerText.replaceAll('&lt;', '<')
    innerText = innerText.replaceAll('&gt;', '>')
    innerText = innerText.replaceAll('\t', '')
    innerText = innerText.replaceAll('\n', '')
    innerText = innerText.replaceAll('</', '\n</')
    innerText = innerText.replaceAll('>', '>\n')
    innerText = innerText.replaceAll(')=>\n', ')=>')
    innerText = innerText.replaceAll('<', '\n<')
    innerText = innerText.replaceAll('\n\n<', '\n<')
    innerText = innerText.replaceAll('  ', '')
    let arrayTemp = innerText.split('\n')
    let array = arrayTemp.filter((item) => item !== '')
    if (array.length == 0) return
    this.pList = []
    array.forEach((item) => this.pList.push(dc('p').txt(item)))
    this.pList[0].level = 0
    this.pList.forEach((item, index) => {
      if (item.innerText.substring(0, 4) == '<!--') {
        item.annotation = 1
      }
      if (
        item.innerText.substring(
          item.innerText.length - 3,
          item.innerText.length
        ) == '-->'
      ) {
        item.annotation = 0
      }
      if (index == 0) return
      if (item.annotation != 0 && this.pList[index - 1].annotation == 1) {
        item.annotation = 1
      }
      if (item.innerText.substring(0, 2) == '</') {
        if (this.pList[index - 1].innerText.substring(0, 2) == '</')
          item.level = this.pList[index - 1].level - 1
        else if (
          this.pList[index - 1].innerText.substring(0, 1) == '<' ||
          this.pList[index - 1].innerText.substring(0, 4) == '<!--'
        ) {
          if (this.pList[index - 1].innerText.substring(0, 6) == '<input')
            item.level = this.pList[index - 1].level - 1
          else item.level = this.pList[index - 1].level
        } else item.level = this.pList[index - 1].level - 1
      } else if (item.innerText.substring(0, 1) == '<') {
        if (
          this.pList[index - 1].innerText.substring(0, 2) == '</' ||
          this.pList[index - 1].innerText.substring(0, 4) == '<!--'
        )
          item.level = this.pList[index - 1].level
        else if (this.pList[index - 1].innerText.substring(0, 1) == '<')
          item.level = this.pList[index - 1].level + 1
        else item.level = this.pList[index - 1].level
      } else {
        if (this.pList[index - 1].innerText.substring(0, 2) == '</')
          item.level = this.pList[index - 1].level
        else if (this.pList[index - 1].innerText.substring(0, 1) == '<')
          item.level = this.pList[index - 1].level + 1
        else item.level = this.pList[index - 1].level
      }
    })
    this.pList.forEach((item) => {
      item.style.textIndent = 10 + 25 * item.level + 'px'
      this.formatItemText(item)
    })
    this.drawCode()
  }
  copy() {
    navigator.clipboard
      .writeText(this.codeString)
      .then(() => {
        if (document.tip != null) {
          document.tip.tip('已复制')
        } else {
          this.refs.tip.innerText = '已复制'
          setTimeout(() => {
            this.refs.tip.innerText = ''
          }, 2000)
        }
      })
      .catch((err) => {
        document.tip.error('Error copying text to clipboard:', err)
      })
  }
  drawCode() {
    this.appendChild(this.element.element)
    this.pList.forEach((item, index) => {
      this.refs.codeNo.appendChild(dc('div', 'a-no').txt(index + 1))
      this.refs.codeContent.appendChild(item)
    })
  }
  formatItemText(item) {
    let text = item.innerText
    item.innerText = ''
    if (item.annotation == 1 || item.annotation == 0)
      item.appendChild(dc('span', 'a-annotation').txt(text))
    else if (
      text.substring(0, 1) == '<' &&
      text.substring(text.length - 1, text.length) == '>'
    )
      this.drawTag(item, text)
    else item.appendChild(dc('span', 'a-tag-font').txt(text))
  }
  drawTag(item, text) {
    if (text.substring(0, 2) == '</') {
      item.appendChild(dc('span', 'a-tag').txt('</'))
      text = text.substring(2, text.length)
      item.appendChild(
        dc('span', 'a-tag-name').txt(text.substring(0, text.length - 1))
      )
      item.appendChild(dc('span', 'a-tag').txt('>'))
    } else if (text.substring(0, 4) == '<!--') {
      item.appendChild(dc('span', 'a-annotation').txt(text))
    } else {
      item.appendChild(dc('span', 'a-tag').txt('<'))
      text = text.substring(1, text.length)

      let backTag
      if (text.substring(text.length - 2, text.length) == '/>') {
        backTag = dc('span', 'a-tag').txt('/>')
        text = text.substring(0, text.length - 2)
      } else {
        backTag = dc('span', 'a-tag').txt('>')
        text = text.substring(0, text.length - 1)
      }
      text = text.replaceAll(': ', ':')
      let array = text.split(' ')
      array.forEach((str, index) => {
        if (index == 0) {
          item.appendChild(dc('span', 'a-tag-name').txt(str))
          return
        }
        if (str.includes('=')) {
          item.appendChild(
            dc('span', 'a-tag-attubite').txt(' ' + str.split('=')[0])
          )
          item.appendChild(dc('span', 'a-tag-equal').txt('='))
          item.appendChild(
            dc('span', 'a-tag-attubite-inner').txt(
              str
                .substring(str.split('=')[0].length + 1, text.length)
                .replaceAll(':', ': ')
            )
          )
        } else
          item.appendChild(
            dc('span', 'a-tag-attubite-inner').txt(
              (' ' + str).replaceAll(':', ': ')
            )
          )
      })
      item.appendChild(backTag)
    }
  }
}
// customElements.define("a-html",HTMLShower)

export default HTMLShower
